﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;

namespace Vibz.Common.Channel
{
    public class SocketClient : SocketPublisher, IDisposable
    {
        private readonly string _remoteAddress;
        private readonly int _remotePortNumber;
        public string ID
        {
            get {
                if (Socket.Connected)
                    return Socket.LocalEndPoint.ToString();
                else
                    return "";
            }
        }
        public SocketClient(string remoteAddress,
                                       int remotePortNumber):this(remoteAddress + ":" + remotePortNumber.ToString())
        { }
        public SocketClient(string remoteLocation)
        {
            string[] loc = remoteLocation.Split(new char[] { ':' });
            if(loc.Length!=2)
                throw new Exception("Invalid location.");

            _remoteAddress = loc[0];
            if (!int.TryParse(loc[1], out _remotePortNumber))
                throw new Exception("Invalid Port.");
            
            Connect();
        }

        
        public void Dispose()
        {
            Disconnect();
        }

        private void Disconnect()
        {
            if (Socket != null)
            {
                Socket.Shutdown(SocketShutdown.Both);
                Socket.Close();
            }
        }

        private void Connect()
        {
            if (!IsConnected)
            {
                try
                {
                    var remoteIpAddress =
                             System.Net.IPAddress.Parse(_remoteAddress);
                    var remoteEndPoint = new System.Net.IPEndPoint(
                                         remoteIpAddress, _remotePortNumber);
                    Socket = new System.Net.Sockets.Socket(
                                AddressFamily.InterNetwork,
                                SocketType.Stream, ProtocolType.Tcp);
                    Socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);

                    Socket.Connect(remoteEndPoint);
                }
                catch (SocketException exc)
                {
                    throw new Exception("Invalid location.", exc);
                }
            }
        }
    }
}